package org.wxl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.wxl.comment.BussinessTypeConstant;
import org.wxl.comment.R;
import org.wxl.domain.fileInfoEntity;
import org.wxl.domain.userEntity;
import org.wxl.mapper.UserMapper;
import org.wxl.service.FileUploadService;
import org.wxl.service.UserService;
import org.wxl.utils.JWTUtils;
import org.wxl.vo.ReqVo.LoginReqVo;
import org.wxl.vo.ReqVo.PasswordChangeReqVo;
import org.wxl.vo.ReqVo.RegisterReqVo;
import org.wxl.vo.RespVo.LoginRespVo;

import org.springframework.http.HttpHeaders;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.UUID;

/**
 * @author 王学良
 */
@Service
@Slf4j
@AllArgsConstructor
public class UserServiceImpl implements UserService {
    private final JWTUtils jwtUtils;
    private final UserMapper userMapper;
    private final AuthenticationManager authenticationManager;
    private final PasswordEncoder passwordEncoder;
    private final FileUploadService fileUploadService;

    /**
     * 登录
     */
    @Override
    public R login(LoginReqVo request) {
        //执行认证
        try {
            //1.创建认证凭证
            Authentication authentication = new UsernamePasswordAuthenticationToken(
                    request.getUserName(),
                    request.getPassword()
            );
            //2.执行认真（内部会调用UserDetailsService）
            Authentication authentication1= authenticationManager.authenticate(authentication);

            LoginRespVo loginRespVo = new LoginRespVo();
            //3.认证成功，生成jwt
            UserDetails userDetails =(UserDetails) authentication1.getPrincipal();
            String username = userDetails.getUsername();
            QueryWrapper<userEntity> queryWrapper = new QueryWrapper<userEntity>()
                    .eq("user_name",username);
            userEntity userEntity = userMapper.selectOne(queryWrapper);
            String token = jwtUtils.generateToken(userDetails);
            loginRespVo.setToken(token);
            loginRespVo.setUserEntity(userEntity);
            return R.ok().data("loginRespVo", loginRespVo).message("登录成功");
        } catch (Exception e) {
            //认证失败
            return R.error().message("登录失败");
        }
    }

    /**
     * 注册
     */
    @Override
    public void register(RegisterReqVo user) {
        if (user.getUserName() == null || user.getPassword() == null || user.getPhone() == null) {
            throw new RuntimeException("用户名或密码或手机号不能为空");
        }
        BeanUtils.copyProperties(user,user);
        userEntity userEntity1 =new userEntity();
        userEntity1.setUserName(user.getUserName());
        userEntity1.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        userEntity1.setPassword(passwordEncoder.encode(user.getPassword()));
        userEntity1.setStatus("0");
        userEntity1.setNickName(user.getUserName());
        userMapper.insert(userEntity1);
    }

    /**
     * 删除用户
     */
    @Override
    public void deleteUserById(String id) {
        QueryWrapper<userEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
        userEntity userEntity = userMapper.selectOne(queryWrapper);
        if (userEntity == null)
        {
            throw new RuntimeException("用户不存在");
        }
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        userEntity.setDeleted("1");
    }

    /**
     * 更新信息
     */
    @Override
    public void updateUser(userEntity userEntity) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            String username = ((UserDetails) principal).getUsername();
            userEntity.setUpdateBy(username);
            userEntity.setUpdateTime(new Date());
        }
        userMapper.updateById(userEntity);
    }

    @Override
    public String passwordChange(PasswordChangeReqVo reqVo) {
        try {
            userEntity userEntity = userMapper.selectById(reqVo.getId());
            userEntity.setPassword(passwordEncoder.encode(reqVo.getNewPassword()));
            userMapper.updateById(userEntity);
        }catch (Exception e)
        {
            return "密码修改失败";
        }
        return "密码修改成功";
    }

    @Override
    public R updateAvatar(MultipartFile file, String uuid) {
        String string = null;
        fileInfoEntity fileInfoEntity =null;
        MultipartFile file1=null;
        byte[] fileContent= null;
        Path path=null;
        try {
            userEntity userEntity = userMapper.selectById(uuid);
            if (!file.isEmpty()) {
                //接收文件保存路径
                fileInfoEntity = fileUploadService.uploadFile(file, uuid, BussinessTypeConstant.USER_AVATAR);
                path= Paths.get(fileInfoEntity.getStoragePath());
                // 更新数据库中头像的存储路径
                userEntity.setAvatar(string);
                userMapper.updateById(userEntity);
            }
            else
            {
                //若上传的文件为空，则使用旧的头像
                path=Paths.get(userEntity.getAvatar());
            }

            //读取文件内容
            fileContent= Files.readAllBytes(path);
            //设置响应头
            HttpHeaders headers= new HttpHeaders();
            if (string != null) {
                headers.setContentDispositionFormData("attachment", new File(string).getName());
            }
            return R.ok().data("fileContent",fileContent);
        } catch (Exception e) {
          return   R.error().message("头像下载有误");
        }
    }


    }

